<?php


/**
 * MYSQL 类 php5以上版本
 */
if (!defined('IN_SYS')) {
	exit ('Hacking attempt');
}

class MysqlBase {
	private $root_path = '';
	private $version = '';
	private $starttime = 0;
	private $timeline = 0;
	private $timezone = 0;
	private $_link_id = NULL;
	private $_settings = array ();
	private $_query_count = 0;
	private $ERROR = array();

	public function __construct() {
		$this->root_path = ROOT_PATH . '/';
	}

	/**
	 * 连接数据库
	 *
	 * param  string  $dbhost   数据库主机名
	 * param  string  $dbuser   数据库用户名
	 * param  string  $dbpw     数据库密码
	 * param  string  $charset  数据库字符集
	 * param  string  $pconnect 持久链接,true为开启,false为关闭
	 * return bool
	 **/
	function connect($dbhost, $dbuser, $dbpw, $dbname = '', $charset = 'utf8', $pconnect = false, $quiet = 0) {
		if ($pconnect) {
			if (!($this->_link_id = @ mysql_pconnect($dbhost, $dbuser, $dbpw))) {
				return false;
			}
		} else {
			$this->_link_id = @ mysql_connect($dbhost, $dbuser, $dbpw, true);

			if (!$this->_link_id) {
				return false;
			}
		}

		$this->version = mysql_get_server_info($this->_link_id);

		mysql_query("SET character_set_connection=$charset, character_set_results=$charset, character_set_client=binary", $this->_link_id);
		mysql_query("SET sql_mode=''", $this->_link_id);

		$this->starttime = time();

		/* 选择数据库 */
		if ($dbname) {
			if (mysql_select_db($dbname, $this->_link_id) === false) {
				if (!$quiet) {
				}
				
				return false;
			} else {
				return true;
			}
		} else {
			return true;
		}
	}

	function select_database($dbname) {
		return mysql_select_db($dbname, $this->_link_id);
	}

	function set_mysql_charset($charset) {
		mysql_query("SET character_set_connection=$charset, character_set_results=$charset, character_set_client=binary", $this->_link_id);
	}

	function fetch_array($query, $result_type = MYSQL_ASSOC) {
		return mysql_fetch_array($query, $result_type);
	}

	function query($sql,$times = 0) {
		if ($this->_link_id === NULL) {
			$this->connect($this->_settings['dbhost'], $this->_settings['dbuser'], $this->_settings['dbpw'], $this->_settings['dbname'], $this->_settings['charset'], $this->_settings['pconnect']);
			$this->_settings = array ();
		}

		$this->_query_count++;
		/* 当当前的时间大于类初始化时间的时候，自动执行 ping 这个自动重新连接操作 */
		if (time() > $this->starttime + 1) {
			mysql_ping($this->_link_id);
		}

		if (!($query = mysql_query($sql, $this->_link_id))) {
			$errno = $this->errno();
			$error = $this->error();

			if (($errno == 126 || $errno == 145 || $errno == 1062 || $errno == 1194 || $errno == 1034 || $errno == 1035) && $times == 0 && (preg_match('/\'\.?\\\\?([\w_]+)\\\\?([\w_]+)\'/', $error, $match) !== false)) {
				/* 如果错误类型为可修复，则尝试修复这个表 */
				if (isset ($match[2])) {
					mysql_query("REPAIR TABLE $match[2]");
					$query = $this->query($sql, 1);
				}
			} else {
				$this->ERROR[] = $this->error();
				return false;
			}
		}
		return $query;
	}

	function affected_rows() {
		return mysql_affected_rows($this->_link_id);
	}

	function error() {
		return mysql_error($this->_link_id);
	}

	function errno() {
		return mysql_errno($this->_link_id);
	}

	function result($query, $row) {
		return @ mysql_result($query, $row);
	}

	function num_rows($query) {
		return mysql_num_rows($query);
	}

	function num_fields($query) {
		return mysql_num_fields($query);
	}

	function free_result($query) {
		return mysql_free_result($query);
	}

	function insert_id() {
		return mysql_insert_id($this->_link_id);
	}

	function fetchRow($query) {
		return mysql_fetch_assoc($query);
	}

	function fetch_fields($query) {
		return mysql_fetch_field($query);
	}

	public function version() {
		return $this->version;
	}

	function ping() {
		return mysql_ping($this->_link_id);
	}

	function escape_string($unescaped_string) {
		return mysql_escape_string($unescaped_string);
	}

	function close() {
		return mysql_close($this->_link_id);
	}

	/* 仿真 Adodb 函数 */
	function selectLimit($sql, $num, $start = 0) {
		if ($start == 0) {
			$sql .= ' LIMIT ' . $num;
		} else {
			$sql .= ' LIMIT ' . $start . ', ' . $num;
		}

		return $this->query($sql);
	}

	function getOne($sql, $limited = false) {
		if ($limited == true) {
			$sql = trim($sql . ' LIMIT 1');
		}

		$res = $this->query($sql);
		if ($res !== false) {
			$row = mysql_fetch_row($res);

			if ($row !== false) {
				return $row[0];
			} else {
				return '';
			}
		} else {
			return false;
		}
	}

	function getAll($sql) {
		$res = $this->query($sql);
		if ($res !== false) {
			$arr = array ();
			while ($row = mysql_fetch_assoc($res)) {
				$arr[] = $row;
			}

			return $arr;
		} else {
			return array();
		}
	}

	/**
	 *  以主键索引形式返回结果集
	 *
	 *  @param  string $sql_statement
	 *  @return array
	 */
	function getAllWithIndex($sql_statement, $index_key) {
		$query = $this->query($sql_statement, 'UNBUFFERED');
		$rtn = array ();
		while ($row = $this->fetch_array($query)) {
			if (is_array($index_key)) {
				$index = '';
				foreach ($index_key as $k) {
					$index .= $index == '' ? $row[$k] : '_' . $row[$k];
				}
				$rtn[$index] = $row;
			} else {
				$rtn[$row[$index_key]] = $row;
			}
		}
		return $rtn;
	}

	function getRow($sql, $limited = false) {
		if ($limited == true) {
			$sql = trim($sql . ' LIMIT 1');
		}

		$res = $this->query($sql);
		if ($res !== false) {
			return mysql_fetch_assoc($res);
		} else {
			return false;
		}
	}

	function getCol($sql) {
		$res = $this->query($sql);
		if ($res !== false) {
			$arr = array ();
			while ($row = mysql_fetch_row($res)) {
				$arr[] = $row[0];
			}

			return $arr;
		} else {
			return false;
		}
	}

	function autoExecute($table, $field_values, $mode = 'INSERT', $where = '', $querymode = '') {
		$field_names = $this->getCol('DESC ' . $table);

		$sql = '';
		if ($mode == 'INSERT') {
			$fields = $values = array ();
			foreach ($field_names AS $value) {
				if (array_key_exists($value, $field_values) == true) {
					$fields[] = $value;
					$values[] = "'" . $field_values[$value] . "'";
				}
			}

			if (!empty ($fields)) {
				$sql = 'INSERT INTO ' . $table . ' (' . implode(', ', $fields) . ') VALUES (' . implode(', ', $values) . ')';
			}
		} else {
			$sets = array ();
			foreach ($field_names AS $value) {
				if (array_key_exists($value, $field_values) == true) {
					$sets[] = $value . " = '" . $field_values[$value] . "'";
				}
			}

			if (!empty ($sets)) {
				$sql = 'UPDATE ' . $table . ' SET ' . implode(', ', $sets) . ' WHERE ' . $where;
			}
		}

		if ($sql) {
			return $this->query($sql, $querymode);
		} else {
			return false;
		}
	}

	function autoReplace($table, $field_values, $update_values, $where = '', $querymode = '') {
		$field_descs = $this->getAll('DESC ' . $table);

		$primary_keys = array ();
		foreach ($field_descs AS $value) {
			$field_names[] = $value['Field'];
			if ($value['Key'] == 'PRI') {
				$primary_keys[] = $value['Field'];
			}
		}

		$fields = $values = array ();
		foreach ($field_names AS $value) {
			if (array_key_exists($value, $field_values) == true) {
				$fields[] = $value;
				$values[] = "'" . $field_values[$value] . "'";
			}
		}

		$sets = array ();
		foreach ($update_values AS $key => $value) {
			if (array_key_exists($key, $field_values) == true) {
				if (is_int($value) || is_float($value)) {
					$sets[] = $key . ' = ' . $key . ' + ' . $value;
				} else {
					$sets[] = $key . " = '" . $value . "'";
				}
			}
		}

		$sql = '';
		if (empty ($primary_keys)) {
			if (!empty ($fields)) {
				$sql = 'INSERT INTO ' . $table . ' (' . implode(', ', $fields) . ') VALUES (' . implode(', ', $values) . ')';
			}
		} else {
			if ($this->version() >= '4.1') {
				if (!empty ($fields)) {
					$sql = 'INSERT INTO ' . $table . ' (' . implode(', ', $fields) . ') VALUES (' . implode(', ', $values) . ')';
					if (!empty ($sets)) {
						$sql .= 'ON DUPLICATE KEY UPDATE ' . implode(', ', $sets);
					}
				}
			} else {
				if (empty ($where)) {
					$where = array ();
					foreach ($primary_keys AS $value) {
						if (is_numeric($value)) {
							$where[] = $value . ' = ' . $field_values[$value];
						} else {
							$where[] = $value . " = '" . $field_values[$value] . "'";
						}
					}
					$where = implode(' AND ', $where);
				}

				if ($where && (!empty ($sets) || !empty ($fields))) {
					if (intval($this->getOne("SELECT COUNT(*) FROM $table WHERE $where")) > 0) {
						if (!empty ($sets)) {
							$sql = 'UPDATE ' . $table . ' SET ' . implode(', ', $sets) . ' WHERE ' . $where;
						}
					} else {
						if (!empty ($fields)) {
							$sql = 'REPLACE INTO ' . $table . ' (' . implode(', ', $fields) . ') VALUES (' . implode(', ', $values) . ')';
						}
					}
				}
			}
		}

		if ($sql) {
			return $this->query($sql, $querymode);
		} else {
			return false;
		}
	}

	/* 获取 SQL 语句中最后更新的表的时间，有多个表的情况下，返回最新的表的时间 */
	function table_lastupdate($tables) {
		if ($this->_link_id === NULL) {
			$this->connect($this->_settings['dbhost'], $this->_settings['dbuser'], $this->_settings['dbpw'], $this->_settings['dbname'], $this->_settings['charset'], $this->_settings['pconnect']);
			$this->_settings = array ();
		}

		$lastupdatetime = '0000-00-00 00:00:00';

		$tables = str_replace('`', '', $tables);
		$this->mysql_disable_cache_tables = str_replace('`', '', $this->mysql_disable_cache_tables);

		foreach ($tables AS $table) {
			if (in_array($table, $this->mysql_disable_cache_tables) == true) {
				$lastupdatetime = '2037-12-31 23:59:59';

				break;
			}

			if (strpos($table, '.') !== false) {
				$tmp = explode('.', $table);
				$sql = 'SHOW TABLE STATUS FROM `' . trim($tmp[0]) . "` LIKE '" . trim($tmp[1]) . "'";
			} else {
				$sql = "SHOW TABLE STATUS LIKE '" . trim($table) . "'";
			}
			$result = mysql_query($sql, $this->_link_id);

			$row = mysql_fetch_assoc($result);
			if ($row['Update_time'] > $lastupdatetime) {
				$lastupdatetime = $row['Update_time'];
			}
		}
		$lastupdatetime = strtotime($lastupdatetime) - $this->timezone + $this->timeline;

		return $lastupdatetime;
	}

	function get_table_name($query_item) {
		$query_item = trim($query_item);
		$table_names = array ();

		/* 判断语句中是不是含有 JOIN */
		if (stristr($query_item, ' JOIN ') == '') {
			/* 解析一般的 SELECT FROM 语句 */
			if (preg_match('/^SELECT.*?FROM\s*((?:`?\w+`?\s*\.\s*)?`?\w+`?(?:(?:\s*AS)?\s*`?\w+`?)?(?:\s*,\s*(?:`?\w+`?\s*\.\s*)?`?\w+`?(?:(?:\s*AS)?\s*`?\w+`?)?)*)/is', $query_item, $table_names)) {
				$table_names = preg_replace('/((?:`?\w+`?\s*\.\s*)?`?\w+`?)[^,]*/', '\1', $table_names[1]);

				return preg_split('/\s*,\s*/', $table_names);
			}
		} else {
			/* 对含有 JOIN 的语句进行解析 */
			if (preg_match('/^SELECT.*?FROM\s*((?:`?\w+`?\s*\.\s*)?`?\w+`?)(?:(?:\s*AS)?\s*`?\w+`?)?.*?JOIN.*$/is', $query_item, $table_names)) {
				$other_table_names = array ();
				preg_match_all('/JOIN\s*((?:`?\w+`?\s*\.\s*)?`?\w+`?)\s*/i', $query_item, $other_table_names);

				return array_merge(array (
					$table_names[1]
				), $other_table_names[1]);
			}
		}

		return $table_names;
	}
	
	public function getError(){
		return $this->ERROR;
	}

}
?>